package com.ksy.common.wxapi;

import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;

import com.google.gson.Gson;
import com.ksy.common.activity.CommonBaseActivity;
import com.ksy.common.login.LoginAction;
import com.ksy.common.login.LoginListenerManager;
import com.ksy.common.login.LoginNoticeInterface;
import com.ksy.common.login.WeChatInfo;
import com.ksy.common.utils.CommonApiUtils;
import com.ksy.common.utils.Constants;
import com.ksy.common.utils.LogTool;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import org.json.JSONException;
import org.json.JSONObject;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

import static com.ksy.common.login.LoginPlatform.Login_Code_WeChat_Cancel;
import static com.ksy.common.login.LoginPlatform.Login_Code_WeChat_Error;
import static com.ksy.common.login.LoginPlatform.Login_Code_WeChat_Success;
import static com.tencent.mm.opensdk.constants.ConstantsAPI.COMMAND_SENDAUTH;

public class WXEntryActivity extends CommonBaseActivity implements IWXAPIEventHandler {

    private String openId;
    private String access_token;
    private Disposable disposable;
    private IWXAPI api;
    private LoginNoticeInterface loginNoticeInterface;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        api = WXAPIFactory.createWXAPI(this, Constants.WeChatID, false);
        api.registerApp(Constants.WeChatID);
        api.handleIntent(getIntent(), this);
        Intent intent = getIntent();
        boolean isHand = intent.getBooleanExtra("isHand", false);
        if (isHand) {
            setResult(Login_Code_WeChat_Cancel);
            login();
        }
    }

    private void login() {
        loginNoticeInterface = new LoginNoticeInterface() {
            @Override
            public void loginNotify(LoginAction loginAction) {
                if (loginAction.loginType == LoginAction.LoginType.WeChat) {
                    if (loginAction.loginState == LoginAction.LoginState.LogOn) {
                        onSuccess((WeChatInfo) loginAction.data);
                    } else if (loginAction.loginState == LoginAction.LoginState.Cancel) {
                        onCancel();
                    } else if (loginAction.loginState == LoginAction.LoginState.Error) {
                        onError((String) loginAction.data);
                    }
                }
            }
        };
        LoginListenerManager.getInstance().registerListener(loginNoticeInterface);
        SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "paopao";
        boolean isSend = api.sendReq(req);
        if (!isSend) {
            onError("微信授权失败");
            return;
        }
    }

    @Override
    protected void onDestroy() {
        if (disposable != null) {
            disposable.dispose();
        }
        if (loginNoticeInterface != null) {
            LoginListenerManager.getInstance().unRegisterListener(loginNoticeInterface);
        }
        super.onDestroy();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        api.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq req) {
        switch (req.getType()) {
            case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:
                break;
            case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:
                break;
            default:
                break;
        }
    }

    @Override
    public void onResp(BaseResp resp) {
        int type = resp.getType();
        if (COMMAND_SENDAUTH == type) {
            //登录的回调
            SendAuth.Resp respAuth = (SendAuth.Resp) resp;
            int errCode = respAuth.errCode;
            String code = respAuth.code;
            if (errCode == BaseResp.ErrCode.ERR_USER_CANCEL) {
                LoginListenerManager.getInstance().notifyListener(new LoginAction<>(LoginAction.LoginType.WeChat, LoginAction.LoginState.Cancel, "微信取消"));
                destroy();
                return;
            }
            if (errCode != BaseResp.ErrCode.ERR_OK) {
                LoginListenerManager.getInstance().notifyListener(new LoginAction<>(LoginAction.LoginType.WeChat, LoginAction.LoginState.Error, "微信授权失败"));
                destroy();
                return;
            }

            final Observable<String> errorOb = Observable.create(new ObservableOnSubscribe<String>() {
                @Override
                public void subscribe(ObservableEmitter<String> e) throws Exception {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("code", "-1");
                    jsonObject.put("errorMsg", "获取信息失败");
                    e.onNext(jsonObject.toString());
                }
            });
            openId = "";
            access_token = "";
            CommonApiUtils.getWeChatToken(code).flatMap(new Function<String, ObservableSource<String>>() {
                @Override
                public ObservableSource<String> apply(String s) throws Exception {
                    try {
                        JSONObject jsonObject = new JSONObject(s);
                        String refresh_token = jsonObject.optString("refresh_token");
                        if (!TextUtils.isEmpty(refresh_token)) {
                            return CommonApiUtils.refreshToken(refresh_token);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                    return errorOb;
                }
            }).flatMap(new Function<String, ObservableSource<String>>() {
                @Override
                public ObservableSource<String> apply(String s) throws Exception {
                    try {
                        JSONObject jsonObject = new JSONObject(s);
                        String openid = jsonObject.optString("openid");
                        String access_token = jsonObject.optString("access_token");
                        openId = openid;
                        WXEntryActivity.this.access_token = access_token;
                        if (!TextUtils.isEmpty(openid) && !TextUtils.isEmpty(access_token)) {
                            return CommonApiUtils.validToken(access_token, openid);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    return errorOb;
                }
            }).flatMap(new Function<String, ObservableSource<String>>() {
                @Override
                public ObservableSource<String> apply(String s) throws Exception {
                    try {
                        JSONObject jsonObject = new JSONObject(s);
                        if (jsonObject.optInt("errcode", -1) == 0) {
                            return CommonApiUtils.getWeChatInfo(access_token, openId);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    return errorOb;
                }
            }).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {
                    disposable = d;
                }

                @Override
                public void onNext(String value) {
                    LogTool.e("onNext" + value);
                    if (TextUtils.isEmpty(value)) {
                        onError(null);
                    }
                    try {
                        JSONObject jsonObject = new JSONObject(value);
                        String openid = jsonObject.optString("openid");
                        if (!TextUtils.isEmpty(openid)) {
                            Gson gson = new Gson();
                            WeChatInfo weChatInfo = gson.fromJson(value, WeChatInfo.class);
                            LoginListenerManager.getInstance().notifyListener(new LoginAction<>(LoginAction.LoginType.WeChat, LoginAction.LoginState.LogOn, weChatInfo));
                            destroy();
                            return;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    onError(null);
                }

                @Override
                public void onError(Throwable e) {
                    LoginListenerManager.getInstance().notifyListener(new LoginAction<>(LoginAction.LoginType.WeChat, LoginAction.LoginState.Error, "获取信息失败"));
                    destroy();
                }

                @Override
                public void onComplete() {
                    LogTool.e("onComplete");
                }
            });
        }
    }

    private void onSuccess(WeChatInfo weChatInfo) {
        LogTool.e("onSuccess    " + weChatInfo);
        Intent intent = new Intent();
        intent.putExtra("weChatInfo", weChatInfo);
        setResult(Login_Code_WeChat_Success, intent);
        destroy();
    }

    private void onError(String msg) {
        Intent intent = new Intent();
        intent.putExtra("errorMsg", msg);
        setResult(Login_Code_WeChat_Error, intent);
        destroy();
    }

    private void onCancel() {
        setResult(Login_Code_WeChat_Cancel);
        destroy();
    }

    private void destroy() {
        finish();
        overridePendingTransition(0, 0);
    }

}